package com.ella.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ella.common.constants.RedisConstants;
import com.ella.common.security.context.AuthenticationContextHolder;
import com.ella.common.security.exception.UsernameAndPasswordNotMatch;
import com.ella.entity.Result;
import com.ella.entity.SysUser;
import com.ella.entity.security.LoginUser;
import com.ella.mapper.SysUserMapper;
import com.ella.service.ISysMenuService;
import com.ella.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ella.utils.JwtUtil;
import com.ella.utils.RedisCache;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

	@Resource
	private AuthenticationManager authenticationManager;
	@Resource
	private ISysMenuService sysMenuService;

	@Resource
	private RedisCache redisCache;

	@Override
	public SysUser getByUsername(String username) {
		return this.getOne(new QueryWrapper<SysUser>().eq("login_name", username));
	}

	@Override
	public Result login(SysUser sysUser) throws Exception {
		String loginName = sysUser.getLoginName();
		String password = sysUser.getPassword();
		String token = null;

		loginPreCheck(loginName, password);
		Authentication authenticate = null;

		try {
			UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginName, password);
			//  将用户名和密码存放在一个当地的线程中，泛型是Authentication
			AuthenticationContextHolder.setContext(authenticationToken);
			authenticate = authenticationManager.authenticate(authenticationToken);
		} catch (Exception e) {
			if (e instanceof BadCredentialsException) {
				throw new UsernameAndPasswordNotMatch("用户名或密码错误");
			} else {
				throw new InternalAuthenticationServiceException(e.getMessage());
			}
		}
		if (Objects.isNull(authenticate)) {
			return Result.error("登录失败");
		}
		//重置redis中的登录次数
		redisCache.setCacheObject(RedisConstants.LOGIN_TRY_KEY_PRE + sysUser.getUserId(), 0);
		LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
		Long userId = loginUser.getUserId();
		String loginUserJson = JSONObject.toJSONString(loginUser);
		System.out.println(loginUserJson);
		redisCache.setCacheObject(RedisConstants.LOGIN_USER_INFO_STORE_PRE + userId, loginUserJson, 30, TimeUnit.MINUTES);
		token = JwtUtil.createJWT(loginUserJson);
		return Result.ok("登录成功").put("authorization", token);
	}

	private void loginPreCheck(String userName, String password) {
		//校验用户名和密码是否是空字符串
		if (StringUtils.isBlank(userName.trim()) || StringUtils.isBlank(password.trim())) {
			throw new UsernameAndPasswordNotMatch("用户名或密码错误");
		}

	}
}
